#!/usr/bin/env python
# encoding: utf-8
"""
    同步模块,将数据库中的内容同步到Redis中
    启动的时候,全量同步,每张表使用不同的增量同步方式,每分钟检索一次.
"""


from source.Lib import orm, Tools
import datetime
import time


def calculate_time(func):
    def wrapper(*args, **kwargs):
        st = time.time()
        ret = func(*args, **kwargs)
        total_time = round(time.time()-st, 3)
        print("-------------------%s:%.3fs---------------" % (func.__name__, total_time))
        return ret
    return wrapper


@calculate_time
def flush_quota(source, target):
    for obj in source.query(orm.Quota).all():
        target.put(f"Quota:{obj.id}", obj.formula)
        target.put(f"Quota:{obj.name}", obj.formula)


@calculate_time
def flush_report(source, target):
    max_date = dict()
    for obj in source.query(orm.Report).all():
        max_date.setdefault(obj.code, obj.date)
        if obj.date >= max_date[obj.code]:
            max_date[obj.code] = obj.date
            target.put(f"Report:{obj.code}", obj.financial)

        target.put(f"Report:{obj.code}:{obj.date.strftime('%Y-%m-%d')}", obj.financial)


@calculate_time
def flush_strategy(source, target):
    for obj in source.query(orm.Strategy).all():
        target.put(f"Strategy:{obj.id}", obj.formulas)
        target.put(f"Strategy:{obj.name}", "|".join(obj.formulas))


@calculate_time
def flush_stock_day(source, target):
    max_date = dict()
    for code in source.query(orm.StockInfo.code).all():
        m = target.get(f"StockDay:{code[0]}")
        if m:
            date = list(map(lambda x: int(x), m.split(',')[-1].split('-')))
        else:
            date = [1, 1, 1]
        max_date.setdefault(code[0], datetime.date(year=date[0], month=date[1], day=date[2]))
        for obj in source.query(orm.StockDay).filter(
            orm.StockDay.code == code[0]).filter(
            orm.StockDay.date >= max_date[code[0]]).all():
            if obj.date >= max_date[obj.code]:
                max_date[obj.code] = obj.date
                target.put(f"StockDay:{obj.code}", obj.get_market())
            target.put(f"StockDay:{obj.code}:{obj.date.strftime('%Y-%m-%d')}", obj.get_market())


@calculate_time
def flush_stock_info(source, target):
    for obj in source.query(orm.StockInfo).all():
        target.put(f"StockInfo:{obj.code}", f"{obj.name},{obj.market},{'|'.join(obj.profession)}")


@calculate_time
def flush_report_quota(source, target):
    for obj in source.query(orm.ReportQuota).all():
        target.put(f"ReportQuota:{obj.id}", f"{'|'.join(obj.codes)},{obj.coverage},{obj.id},{obj.name}")
        target.put(f"ReportQuota:{obj.name}", f"{'|'.join(obj.codes)},{obj.coverage},{obj.id},{obj.name}")


@calculate_time
def flush_industry(source, target):
    for obj in source.query(orm.Industry).all():
        target.put(f"Industry:{obj.id}", f"{'|'.join(obj.codes)}")
        target.put(f"Industry:{obj.name}", f"{'|'.join(obj.codes)}")


@calculate_time
def flush_market_key_word(source, target):
    for obj in source.query(orm.MarketKeyWord).all():
        target.put(f"MarketKeyWord:{obj.pos}", obj.name)
        target.put(f"MarketKeyWord:{obj.name}", obj.pos)


@calculate_time
def all_flush():
    target = Tools.Outer()
    source = orm.Session()
    flush_quota(source, target)
    flush_strategy(source, target)
    flush_stock_info(source, target)
    flush_report_quota(source, target)
    flush_industry(source, target)
    flush_market_key_word(source, target)
    flush_stock_day(source, target)
    flush_report(source, target)

    source.close()


if __name__ == '__main__':
    all_flush()
